package handler

import (
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
	v1 "server_go/api/v1"
	"server_go/internal/service"
)

type UserHandler interface {
	Register(ctx *gin.Context)
	Login(ctx *gin.Context)
	GetUserProfile(ctx *gin.Context)
	AddUser(ctx *gin.Context)
	DeleteUser(ctx *gin.Context)
	UpdateUser(ctx *gin.Context)
	GetAllUser(ctx *gin.Context)
	UpdateUserProfile(ctx *gin.Context)
}

type userHandler struct {
	*Handler
	userService service.UserService
}

func NewUserHandler(handler *Handler, userService service.UserService) UserHandler {
	return &userHandler{
		Handler:     handler,
		userService: userService,
	}
}

func (h *userHandler) Register(ctx *gin.Context) {
	req := new(v1.RegisterRequest)
	if err := ctx.ShouldBind(&req); err != nil {
		h.logger.Error("params error", zap.Any("error", err))
		v1.HandleError(ctx, http.StatusBadGateway, v1.ErrBadGateway, nil)
		return
	}
	h.logger.Info("Register Information")
	if err := h.userService.Register(req); err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, err, nil)
		return
	}
	v1.HandleSuccess(ctx, nil)
}

func (h *userHandler) Login(ctx *gin.Context) {
	req := new(v1.LoginRequest)
	if err := ctx.ShouldBind(&req); err != nil {
		h.logger.Error("params error", zap.Any("error", err))
		v1.HandleError(ctx, http.StatusBadGateway, v1.ErrBadGateway, nil)
		return
	}
	h.logger.Info("Login Information")
	resp, err := h.userService.Login(req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, err, nil)
		return
	}
	v1.HandleSuccess(ctx, resp)
}

func (h *userHandler) GetUserProfile(ctx *gin.Context) {
	req := new(v1.GetUserProfileRequest)
	if err := ctx.ShouldBindUri(&req); err != nil {
		h.logger.Error("params error", zap.Any("error", err))
		v1.HandleError(ctx, http.StatusBadGateway, v1.ErrBadGateway, nil)
		return
	}
	resp, err := h.userService.GetUserByAccount(req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, err, nil)
		return
	}
	v1.HandleSuccess(ctx, resp)
}
func (h *userHandler) AddUser(ctx *gin.Context) {
	req := new(v1.AddUserRequest)
	if err := ctx.ShouldBind(&req); err != nil {
		h.logger.Error("params error", zap.Any("error", err))
		v1.HandleError(ctx, http.StatusBadGateway, v1.ErrBadGateway, nil)
		return
	}
	h.logger.Info("AddUser Information")
	if err := h.userService.AddUser(req); err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, err, nil)
		return
	}
	v1.HandleSuccess(ctx, nil)
}
func (h *userHandler) DeleteUser(ctx *gin.Context) {
	req := new(v1.DeleteUserRequest)
	if err := ctx.ShouldBindUri(&req); err != nil {
		h.logger.Error("params error", zap.Any("error", err))
		v1.HandleError(ctx, http.StatusBadGateway, v1.ErrBadGateway, nil)
		return
	}
	h.logger.Info("DeleteUser Information")
	resp, err := h.userService.DeleteUser(req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, err, nil)
		return
	}
	v1.HandleSuccess(ctx, resp)
}
func (h *userHandler) UpdateUser(ctx *gin.Context) {
	req := new(v1.UpdateUserRequest)
	if err := ctx.ShouldBind(&req); err != nil {
		h.logger.Error("params error", zap.Any("error", err))
		v1.HandleError(ctx, http.StatusBadGateway, v1.ErrBadGateway, nil)
		return
	}
	h.logger.Info("UpdateUser Information", zap.Any("req", req))
	if err := h.userService.UpdateUser(req); err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, err, nil)
		return
	}
	v1.HandleSuccess(ctx, nil)
}
func (h *userHandler) GetAllUser(ctx *gin.Context) {
	req := new(v1.GetAllUserRequest)
	if err := ctx.ShouldBind(&req); err != nil {
		h.logger.Error("params error", zap.Any("error", err))
		v1.HandleError(ctx, http.StatusBadGateway, v1.ErrBadGateway, nil)
		return
	}
	h.logger.Info("GetAllUser Information")
	resp, err := h.userService.GetAllUser(req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, err, nil)
		return
	}
	v1.HandleSuccess(ctx, resp)
}

func (h *userHandler) UpdateUserProfile(ctx *gin.Context) {
	req := new(v1.UpdateUserProfileReq)
	if err := ctx.ShouldBind(&req); err != nil {
		h.logger.Error("params error", zap.Any("error", err))
		v1.HandleError(ctx, http.StatusBadGateway, v1.ErrBadGateway, nil)
		return
	}

	resp, err := h.userService.UpdateUserProfile(req)
	if err != nil {
		v1.HandleError(ctx, http.StatusInternalServerError, err, nil)
		return
	}

	v1.HandleSuccess(ctx, resp)
}
